import pandas as pd
import numpy as np
from datetime import datetime
import logging

logger = logging.getLogger(__name__)


class DataPreprocessor:
    """数据预处理工具"""

    def prepare_data(self, historical_data):
        """
        准备和清洗历史数据

        Args:
            historical_data: 列表格式的历史数据
            [{"timestamp": "2024-01-01 00:00:00", "request_count": 100}, ...]

        Returns:
            DataFrame with columns ['timestamp', 'value']
        """
        try:
            # 转换为DataFrame
            df = pd.DataFrame(historical_data)

            # 重命名列
            if 'request_count' in df.columns:
                df.rename(columns={'request_count': 'value'}, inplace=True)

            # 转换时间戳
            df['timestamp'] = pd.to_datetime(df['timestamp'])

            # 按时间排序
            df = df.sort_values('timestamp')

            # 处理缺失值
            df['value'] = df['value'].fillna(method='ffill').fillna(0)

            # 处理异常值（使用3-sigma原则）
            df = self._handle_outliers(df)

            # 确保时间序列连续（填充缺失的时间点）
            df = self._fill_missing_timestamps(df)

            logger.info(f"数据预处理完成，数据点数: {len(df)}")
            return df

        except Exception as e:
            logger.error(f"数据预处理失败: {str(e)}")
            raise

    def _handle_outliers(self, df, sigma=3):
        """处理异常值"""
        mean = df['value'].mean()
        std = df['value'].std()

        # 将超过3个标准差的值替换为边界值
        upper_bound = mean + sigma * std
        lower_bound = max(0, mean - sigma * std)

        df.loc[df['value'] > upper_bound, 'value'] = upper_bound
        df.loc[df['value'] < lower_bound, 'value'] = lower_bound

        return df

    def _fill_missing_timestamps(self, df):
        """填充缺失的时间点（按小时）"""
        # 创建完整的时间范围
        full_range = pd.date_range(
            start=df['timestamp'].min(),
            end=df['timestamp'].max(),
            freq='H'
        )

        # 重新索引并填充
        df = df.set_index('timestamp')
        df = df.reindex(full_range, fill_value=0)
        df = df.reset_index()
        df.columns = ['timestamp', 'value']

        # 使用线性插值填充0值
        df['value'] = df['value'].replace(0, np.nan).interpolate(method='linear').fillna(0)

        return df